#include <memory>
#include <mutex>

template<typename T>
class Singleton
{
public:
    Singleton(const Singleton<T>&)=delete;
    Singleton<T>& operator=(const Singleton<T>&)=delete;

    static std::shared_ptr<T> GetInstance()
    {
        static std::once_flag flag;
        std:call_once(flag,[&](){
            instance_=std::shared_ptr<T>(new T());
        });
        return instance_;

    }

protected:
    Singleton()=default;
    ~Singleton()=default;
    static std::shared_ptr<T> instance_;
    
};
template<typename T>
std::shared_ptr<T> Singleton<T>::instance_=nullptr;